home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
cfixvb
/
curr2vb.asm
next >
Wrap
Assembly Source File
|
1991-09-06
|
3KB
|
137 lines
page ,132
.model large, basic
.286
comment |
This routine can help you maintain currency variables to a fixed
number of decimal places. This is the VB version of the code.
----------------------------------------------------------------------
Written by Jim Mack, CIS 76630,2012, bix "jsmack"
Copyright 1991, Editing Services Co. All rights reserved.
Free for non-commercial use: commercial rights freely granted on
written request, with acknowledgement of copyright.
----------------------------------------------------------------------
DECLARE SUB CurrFix lib "currfix.dll" (CurrVal@, ByVal Places%, ByVal Truncate%)
Adjusts the passed Currency variable (if required) to remove one
or more digits to the right of the decimal point.
CurrVal@ is directly modified, not returned as a function result.
Places% may be 0 to 3 and will result in a value with the indicated
number of digits beyond the decimal point. Other values are ingored
with CurrVal@ left unchanged.
If Truncate% is non-zero the excess places are simply removed,
otherwise the value is rounded using traditional financial rounding.
Performs the equivalent of the following Basic code:
CVal@ = INT((CVal@ * (10^n)) + .5) / (10^n)
Floating point is avoided for maximum speed.
----------------------------------------------------------------------
|
by equ <byte ptr> ;; convenient shorthand macros
wo equ <word ptr>
bit equ <1 shl>
EPNegate MACRO MemArg ;; extended-precision integer unary negate
xor ax, ax
neg wo MemArg
not wo MemArg+2
not wo MemArg+4
not wo MemArg+6
cmc
adc MemArg+2, ax
adc MemArg+4, ax
adc MemArg+6, ax
ENDM
;---------------------------------------------------------------------------
.code
PTable dw 10000, 1000, 100, 10
CurrFix PROC uses di si, currval:dword, places, truncate
LOCAL sgn
lds si, currval ; --> currency value
mov sgn, 0
test by 7[si], bit 7 ; negative?
jz @f
dec sgn ; yes, indicate for exit
EPNegate [si] ; and make positive (negate -number)
@@:
mov bx, places
cmp bx, 0
jl cferr
cmp bx, 3
jna @f ; all OK
cferr: jmp cfx90 ; ignore if > 3 or < 0
@@: add bx, bx
mov cx, PTable[bx]
mov ax, 6[si]
xor dx, dx
div cx
mov 6[si], ax
mov ax, 4[si]
div cx
mov 4[si], ax
mov ax, 2[si]
div cx
mov 2[si], ax
mov ax, [si]
div cx
mov [si], ax ; value MOD [CX] in DX now
shr cx, 1
xor ax, ax
cmp truncate, ax ; round or truncate?
jne @f ; truncate: skip next test
cmp dx, cx ; clear carry if remainder >= half
jc @f
cmc
adc [si], ax
adc 2[si], ax
adc 4[si], ax
adc 6[si], ax
;
; Multiplying will restore zeroes to the last places
;
@@:
shl cx, 1 ; restore divisor as multiplier
mov ax, [si]
mul cx
mov di, dx ; accumulate partial product
mov [si], ax
mov ax, 2[si]
mul cx
mov bx, dx
mov 2[si], ax
mov ax, 4[si]
mul cx
push dx
mov 4[si], ax
mov ax, 6[si]
mul cx
mov 6[si], ax
pop dx
add 2[si], di ; shifted partial product in DX:BX:DI
adc 4[si], bx
adc 6[si], dx
cmp sgn, 0 ; was negative?
je cfx90
EPNegate [si] ; if so, make negative again
cfx90:
ret
CurrFix ENDP
END